﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;

namespace WebFabricator.org
{
    //http://develoq.net/2010/custom-controller-factory-in-asp-net-mvc/
    //http://geekswithblogs.net/sankarsan/archive/2009/01/18/developing-custom-routehandler.aspx
    /// <summary>
    /// Abstract factory that creates the fabricator (the root of the processing pipeline) and populates it 
    /// by first adding the adorners defined in the configuration file and then adding those retrieved from 
    /// querying the fabric for the adorner namespace.
    /// </summary>
    [Namespace(typeof(WebFabricatorFactory<>))]
    public sealed class WebFabricatorFactory<T> : IWebFabricatorFactory<T>
    {
        public WebFabricatorFactory()
            : base()
        { 
        
        }

        public IWebFabricator<IWebFabric<T>> CreateFabricator(IWebFabric<T> fabric)
        {

#region replace with ConfigurationValueProvider

            IAdorner<T> first = null;
            new WebFabricatorCatalog<T>(fabric)
                .Aggregate<Type, IAdorner<T>>(first, (currentAdorner, type) =>
                {
                    Adorner<T> adorner = Activator.CreateInstance(type) as Adorner<T>;
                    if (adorner != null)
                    {
                        //adorner = adorner.Wrap();
                        adorner.Initialize(fabric.Context);
                        if (currentAdorner == null)
                        {
                            first = adorner;
                            return adorner;
                        }
                        else
                        {
                            return currentAdorner.Next(adorner);
                        }
                    }
                    return currentAdorner;
                });
            return first;
#endregion
            
        }

        public void ReleaseFabricator(IWebFabricator<IWebFabric<T>> fabricator)
        {
            var disposable = fabricator as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }

    }
}
